package com.dxf.sysadmin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxf.common.utils.GlobalConstant;
import com.dxf.common.utils.ResultJson;
import com.dxf.sysadmin.entity.*;
import com.dxf.sysadmin.entity.vo.EvaluteRecordVo;
import com.dxf.sysadmin.entity.vo.EvaluteTargetVo;
import com.dxf.sysadmin.mapper.EvaluteRecordMapper;
import com.dxf.sysadmin.service.*;
import jdk.nashorn.internal.ir.ReturnNode;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 评价记录 服务实现类
 */
@Slf4j
@Service
public class EvaluteRecordServiceImpl extends ServiceImpl<EvaluteRecordMapper, EvaluteRecord> implements EvaluteRecordService {
    @Autowired
    StudentService studentService;
    @Autowired
    CourseClazzTeacherService courseClazzTeacherService;
    @Autowired
    EvaluteTargetService evaluteTargetService;
    @Autowired
    EvaluteItemService evaluteItemService;
    @Autowired
    EmpService empService;
    @Autowired
    CourseService courseService;
    @Autowired
    EvaluteResultService evaluteResultService;
    @Autowired
    DeptService deptService;
    @Autowired
    ClazzService clazzService;

    private double testsScore=0;

    /**
     * @Description: 学生评教生成
     * @Auther: dxf
     * @Param uid 用户id
     * @Param tid 任务id
     */
    @Override
    public ResultJson student(Long uid, Long tid) {
        List<EvaluteRecordVo> recordVoList = new ArrayList<>();
        //对应学生
        Student one = studentService.getOne(new QueryWrapper<Student>().
                lambda().eq(Student::getUserId, uid));
        //对应课表
        List<CourseClazzTeacher> list = courseClazzTeacherService.
                list(new QueryWrapper<CourseClazzTeacher>().
                        lambda().eq(CourseClazzTeacher::getClazzId, one.getClazzId()));
        //学生评教指标
        List<EvaluteTarget> targets = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                lambda().eq(EvaluteTarget::getTypeId, GlobalConstant.STUDENT_TYPE_ID).eq(EvaluteTarget::getParentId, 0));
        String deep = "";
        getChild(targets, deep);

        list.forEach(x -> {
            EvaluteRecordVo evaluteRecordVo = new EvaluteRecordVo();
            evaluteRecordVo.setUserId(uid);
            evaluteRecordVo.setCourseId(x.getCourseId());
            evaluteRecordVo.setTeacherId(x.getTeacherId());
            evaluteRecordVo.setTaskId(tid);
            evaluteRecordVo.setCourse(courseService.getById(x.getCourseId()));
            evaluteRecordVo.setEmp(empService.getById(x.getTeacherId()));

            evaluteRecordVo.setTargets(targets);
            //判断该课程是否评教
            List<EvaluteRecord> list1 = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                    eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getCourseId, x.getCourseId()).
                    eq(EvaluteRecord::getTeacherId, x.getTeacherId()));
            if(list1.size()>0){
                evaluteRecordVo.setStatus(1);
            }
            recordVoList.add(evaluteRecordVo);
        });
        return ResultJson.ok().data("rows", recordVoList).
                data("total", recordVoList.size());
    }

    /**
     * 评教数据插入
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultJson insertRecord(List<EvaluteRecord> recordList) {
        saveBatch(recordList);
        double score = 1;
        testsScore=0;
        List<Long> ids = recordList.stream().map(EvaluteRecord::getTargetId).collect(Collectors.toList());
        //所有叶子节点
        List<EvaluteTarget> evaluteTargets = (List<EvaluteTarget>) evaluteTargetService.listByIds(ids);
        Long typeId = evaluteTargets.get(0).getTypeId();
        Long taskId = recordList.get(0).getTaskId();
        Long teacherId = recordList.get(0).getTeacherId();
        getChildAndScore(evaluteTargets, score, recordList,typeId);
        //设置保留位数
        DecimalFormat df=new DecimalFormat("0.00");
        EvaluteResult evaluteResult = new EvaluteResult();
        evaluteResult.setScore( Double.parseDouble(df.format(testsScore)));
        evaluteResult.setTaskId(taskId);
        evaluteResult.setTeacherId(teacherId);
        evaluteResult.setTypeId(typeId);
        evaluteResultService.save(evaluteResult);
        return ResultJson.ok();
    }

    /**
     *教师自评生成
     */
    @Override
    public ResultJson selfTeacher(Long uid, Long tid) {
        //对应教师
        Emp one = empService.getOne(new QueryWrapper<Emp>().
                lambda().eq(Emp::getUserId, uid));
        //教师自评指标
        List<EvaluteTarget> targets = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                lambda().eq(EvaluteTarget::getTypeId, GlobalConstant.TEACHER_ZERO_SELF_TYPE_ID).eq(EvaluteTarget::getParentId, 0));
        String deep = "";
        getChild(targets, deep);
        EvaluteRecordVo evaluteRecordVo = new EvaluteRecordVo();
        evaluteRecordVo.setUserId(uid);
        evaluteRecordVo.setTeacherId(one.getId());
        evaluteRecordVo.setTaskId(tid);

        evaluteRecordVo.setTargets(targets);
        return ResultJson.ok().data("recordVo", evaluteRecordVo);
    }

    /**
     *教师互评生成
     */
    @Override
    public ResultJson mutualTeacher(Long uid, Long tid) {
        List<EvaluteRecordVo> recordVoList = new ArrayList<>();
        //对应教师
        Emp one = empService.getOne(new QueryWrapper<Emp>().
                lambda().eq(Emp::getUserId, uid));
        //同部门教师
        List<Emp> list = empService.list(new QueryWrapper<Emp>().
                lambda().eq(Emp::getDeptId, one.getDeptId()).
                ne(Emp::getId,one.getId()).ne(Emp::getDuty,1));
        //教师互评指标
        List<EvaluteTarget> targets = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                lambda().eq(EvaluteTarget::getTypeId, GlobalConstant.TEACHER_ZERO_MUTUAL_TYPE_ID).eq(EvaluteTarget::getParentId, 0));
        String deep = "";
        getChild(targets, deep);
        list.forEach(x -> {
            EvaluteRecordVo evaluteRecordVo = new EvaluteRecordVo();
            evaluteRecordVo.setUserId(uid);
            evaluteRecordVo.setTeacherId(x.getId());
            evaluteRecordVo.setTaskId(tid);
            evaluteRecordVo.setEmp(x);

            evaluteRecordVo.setTargets(targets);
            //判断该老师是否评教
            List<EvaluteRecord> list1 = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                    eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, x.getId()));
            if(list1.size()>0){
                evaluteRecordVo.setStatus(1);
            }
            recordVoList.add(evaluteRecordVo);
        });
        return ResultJson.ok().data("rows", recordVoList).
                data("total", recordVoList.size());
    }

    /**
     *室主任评教生成
     */
    @Override
    public ResultJson director(Long uid, Long tid) {
        List<EvaluteRecordVo> recordVoList = new ArrayList<>();
        //对应教师
        Emp one = empService.getOne(new QueryWrapper<Emp>().
                lambda().eq(Emp::getUserId, uid));
        //同部门教师 .ne(Emp::getId,one.getId()))
        List<Emp> list = empService.list(new QueryWrapper<Emp>().
                lambda().eq(Emp::getDeptId, one.getDeptId()).ne(Emp::getId,one.getId()));
        //室主任评教指标
        List<EvaluteTarget> targets = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                lambda().eq(EvaluteTarget::getTypeId, GlobalConstant.TEACHER_ONE_TYPE_ID).eq(EvaluteTarget::getParentId, 0));
        String deep = "";
        getChild(targets, deep);

        list.forEach(x -> {
            EvaluteRecordVo evaluteRecordVo = new EvaluteRecordVo();
            evaluteRecordVo.setUserId(uid);
            evaluteRecordVo.setTeacherId(x.getId());
            evaluteRecordVo.setTaskId(tid);
            evaluteRecordVo.setEmp(x);

            evaluteRecordVo.setTargets(targets);
            //判断该老师是否评教
            List<EvaluteRecord> list1 = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                    eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, x.getId()));
            if(list1.size()>0){
                evaluteRecordVo.setStatus(1);
            }
            recordVoList.add(evaluteRecordVo);
        });
        return ResultJson.ok().data("rows", recordVoList).
                data("total", recordVoList.size());
    }

    /**
     *系主任评教生成
     */
    @Override
    public ResultJson department(Long uid, Long tid) {
        List<EvaluteRecordVo> recordVoList = new ArrayList<>();
        //所有系员工
        List<Emp> empList=new ArrayList<>();
        //对应教师
        Emp one = empService.getOne(new QueryWrapper<Emp>().
                lambda().eq(Emp::getUserId, uid));
        //系部门
        List<Dept> deptList = deptService.list(new QueryWrapper<Dept>().
                lambda().eq(Dept::getParentId, one.getDeptId()));
        deptList.forEach(y->{
            //部门员工
            empList.addAll(empService.list(new QueryWrapper<Emp>().
                    lambda().eq(Emp::getDeptId, y.getId()).ne(Emp::getDuty,1)));
        });
        //系主任评教指标
        List<EvaluteTarget> targets = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                lambda().eq(EvaluteTarget::getTypeId, GlobalConstant.TEACHER_TWO_TYPE_ID).eq(EvaluteTarget::getParentId, 0));
        String deep = "";
        getChild(targets, deep);

        empList.forEach(x -> {
            EvaluteRecordVo evaluteRecordVo = new EvaluteRecordVo();
            evaluteRecordVo.setUserId(uid);
            evaluteRecordVo.setTeacherId(x.getId());
            evaluteRecordVo.setTaskId(tid);
            evaluteRecordVo.setEmp(x);

            evaluteRecordVo.setTargets(targets);
            //判断该老师是否评教
            List<EvaluteRecord> list1 = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                    eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, x.getId()));
            if(list1.size()>0){
                evaluteRecordVo.setStatus(1);
            }
            recordVoList.add(evaluteRecordVo);
        });
        return ResultJson.ok().data("rows", recordVoList).
                data("total", recordVoList.size());
    }

    /**
     *判断教师是否自评
     */
    @Override
    public ResultJson selfDecide(Long uid, Long tid) {
        Emp one = empService.getOne(new QueryWrapper<Emp>().
                lambda().eq(Emp::getUserId, uid));
        List<EvaluteRecord> list1 = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, one.getId()));
        boolean decide=false;
        if(list1.size()>0){
            decide=true;
        }
        return ResultJson.ok().data("decide", decide);
    }

    /**
     *教师自评查看记录
     */
    @Override
    public ResultJson tSelfResult(Long uid, Long tid) {
        Emp one = empService.getOne(new QueryWrapper<Emp>().lambda().eq(Emp::getUserId, uid));
        List<EvaluteRecord> list = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, one.getId()));
        return selfTeacher(uid, tid).data("answer",list);
    }

    /**
     *教师互评查看记录
     */
    @Override
    public ResultJson tMutualResult(Long uid, Long tid, Long id) {
        List<EvaluteRecord> list = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, id));
        return mutualTeacher(uid, tid).data("answer",list);
    }

    /**
     *室评教查看记录
     */
    @Override
    public ResultJson directorResult(Long uid, Long tid, Long id) {
        List<EvaluteRecord> list = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, id));
        return director(uid, tid).data("answer",list);
    }

    /**
     *系评教查看记录
     */
    @Override
    public ResultJson departmentResult(Long uid, Long tid, Long id) {
        List<EvaluteRecord> list = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getTeacherId, id));
        return department(uid, tid).data("answer",list);
    }

    /**
     *学生查看评教记录
     */
    @Override
    public ResultJson studentResult(Long uid, Long tid, Long cid, Long id) {
        List<EvaluteRecord> list = list(new QueryWrapper<EvaluteRecord>().lambda().eq(EvaluteRecord::getTaskId, tid).
                eq(EvaluteRecord::getUserId, uid).eq(EvaluteRecord::getCourseId, cid).eq(EvaluteRecord::getTeacherId,id));
        return student(uid, tid).data("answer",list);
    }

    /**
     *班级学生评教情况
     */
    @Override
    public ResultJson studentSituation(Long cid, Long tid){
        return null;
    }

    /**
     * 递归算分(从叶子节点回退)
     */
    private void getChildAndScore(List<EvaluteTarget> list, double score, List<EvaluteRecord> recordList,Long typeId) {
        for (EvaluteTarget x : list) {
            double y;
            //找到节点对应记录
            List<EvaluteRecord> boys = recordList.stream().filter(s -> s.getTargetId().equals(x.getId())).collect(Collectors.toList());
            if (boys.size() != 0){
                Long itemId = boys.get(0).getItemId();
                //对应选项
                EvaluteItem byId = evaluteItemService.getById(itemId);
                y= x.getWeight()*byId.getScore();
            }else {
                y= x.getWeight()*score;
            }
            //同级对象
            List<EvaluteTarget> listOne = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                    lambda().eq(EvaluteTarget::getParentId, x.getParentId()).
                    eq(EvaluteTarget::getTypeId,typeId));
            //同级权之和
            double denominator=0;
            for (EvaluteTarget target : listOne) {
                denominator+=target.getWeight();
            }
            score=(y/denominator);
            //获取父级
            List<EvaluteTarget> listTwo = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                    lambda().eq(EvaluteTarget::getId, x.getParentId()));
            if (listTwo.size() != 0){
                //有父级则进入父级
                getChildAndScore(listTwo,score,recordList,typeId);
            }else {
                //每层求和
                testsScore+=score;
            }

        }

    }

    /**
     * 递归获取层级数据
     */
    private void getChild(List<EvaluteTarget> list, String deep) {
        //深度++
        deep = deep + ".0";
        for (EvaluteTarget x : list) {
            //获取子级
            List<EvaluteTarget> listOne = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
                    lambda().eq(EvaluteTarget::getParentId, x.getId()));
            String substring = deep.substring(deep.length() - 1);
            //宽度++
            int s = Integer.parseInt(substring) + 1;
            deep = deep.substring(0, deep.length() - 1) + s;
            x.setName(deep + "." + x.getName());
            if (listOne.size() != 0) {
                x.setTargets(listOne);
                getChild(listOne, deep);
            } else {
                //获取选项
                List<EvaluteItem> items = evaluteItemService.list(new QueryWrapper<EvaluteItem>().
                        lambda().eq(EvaluteItem::getTargetId, x.getId()).orderByAsc(EvaluteItem::getSortCode));
                x.setItems(items);
            }
        }
//        list.forEach(x->{
//
//            //获取子级
//            List<EvaluteTarget> listOne = evaluteTargetService.list(new QueryWrapper<EvaluteTarget>().
//                    lambda().eq(EvaluteTarget::getParentId, x.getId()));
//            if(listOne.size()!=0){
//                x.setTargets(listOne);
//                getChild(listOne);
//            }else {
//                //获取选项
//                List<EvaluteItem> items = evaluteItemService.list(new QueryWrapper<EvaluteItem>().
//                        lambda().eq(EvaluteItem::getTargetId,x.getId()).orderByAsc(EvaluteItem::getSortCode));
//                x.setItems(items);
//            }
//
//        });
    }
}
